package Demo;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2023-01-08
 * Time: 16:20
 */

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ReentrantLock的用法：
 * lock（） ： 加锁，弱国获取不到锁就死等
 * trylock（） ： 加锁，如果获取不到锁，等待一定时间之后就放弃加锁
 * unlock（） ： 解锁
 */
public class Thread_Demo14 {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        lock.lock();
        Condition condition = lock.newCondition();
        // 中间执行加锁代码，但是由于代码过多的情况下，unlock解锁操作容易忘记
        // 因此 通常配合try-finally使用
        try{
            // working 需要加锁的任务
        }finally {
            lock.unlock(); // 解锁操作
        }

        lock.tryLock(); // 不需要手动释放锁，等待一定时间后不加锁自动放弃
        try{
            // working
        }finally {
            lock.unlock();
        }
    }


    /**
     *  ReentrantLock 和 synchronized 区别：
     *  1） synchronized 是一个关键字，是JVM内部实现的，ReentantLock是标准库的一个类在JVM外实现的（基于JAVA)
     *  2) synchronized 使用时不需要手都释放锁，ReentrantLock需要手动释放，但容易忘了unlock
     *  3） synchronized 在申请加锁失败时，会死等（升级为挂起锁），ReentrantLock可以通过trylock方式等待一段时间就放弃
     *  4） synchronized时一个非公平锁（”雨露均沾“），ReentrantLock默认是非公平锁
     *  5） ReentrantLock提供了一个构造方法 ReentrantLock（true）-表示公平锁
     *
     *  关于唤醒机制，synchronized 通过Objuect（）的wait/notify实现等待-唤醒操作，每次唤醒的是一个随机等待的线程（可以通过打破循环的方式控制顺序）
     *  ReentrantLock 搭配 Condition
     */


    /**
     * 关于锁的选择：
     * 锁竞争不激烈的时候，使用synchronized效率更高，自动释放锁更方便
     * 锁竞争激烈的时候，使用ReentrantLock搭配trylock更灵活控制加锁行为，而不是死等
     * 如果需要使用公平锁，使用ReentranLock（内置公平锁） synchronized是非公平锁
     */
}
